package com.gjzhao.fmmall.service.impl;

import com.gjzhao.fmmall.entity.Orders;
import com.gjzhao.fmmall.service.ApiOrderService;
import com.gjzhao.fmmall.vo.RespResultVO;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * @Description: ApiOrderServiceImpl
 * @Author: gjzhao
 * @Date Created in 2022-02-08 9:05 下午
 */
@Service
public class ApiOrderServiceImpl implements ApiOrderService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private RestTemplate restTemplate;


    /**
     * 添加订单
     *
     * @param cartIds
     * @param order
     * @return
     */
    @Override
    @HystrixCommand(fallbackMethod = "addOrderFallBack",
        commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"), //如果超过3s还未调通服务，将进行服务降级
            @HystrixProperty(name="circuitBreaker.enabled",value="true"), //启⽤服务熔断
            @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value="10000"),//时间[熔断时间]
            @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value="10"),//请求次数
            @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value="50"),//服务错误率
        }
    )
    public RespResultVO addOrder(String cartIds, Orders order) {


        logger.info("-----使用rest方式调用服务:----");
        RespResultVO respResultVO = restTemplate.postForObject("http://order-add/orders/add?cartIds=" + cartIds, order, RespResultVO.class);
        //RespResultVO respResultVO = restTemplate.postForObject("http://order-add-hystrix/orders/add?cartIds=" + cartIds, order, RespResultVO.class); // 测试在服务提供者开启降级服务
        logger.info("-----使用rest方式调用结果:{}----", respResultVO);
        return respResultVO;
    }

    // 如果 addOrder方法使用ribbon调用服务在3s内没有响应，将进行服务降级调用addOrderFallBack方法 [降级方法与调用方法拥有一样的参数与返回类型]
    public RespResultVO addOrderFallBack(String cartIds, Orders order) {

        logger.info("-----调用order-add服务超时，进行服务降级------");
        //logger.info("-----调用order-add-hystrix服务超时，进行服务降级------");
        logger.info("-----addOrder降级----");
        return RespResultVO.failed("网络异常，添加订单失败，请稍后再试");
    }

    /**
     * 获取订单信息
     *
     * @param orderId
     * @return
     */
    @Override
    @HystrixCommand(fallbackMethod = "getOrderFallBack",
        commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"), //如果超过3s还未调通服务，将进行服务降级
            @HystrixProperty(name="circuitBreaker.enabled",value="true"), //启⽤服务熔断
            @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value="10000"),//时间[熔断时间]
            @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value="10"),//请求次数
            @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value="50"),//服务错误率
        }
    )
    public RespResultVO getOrder(String orderId) {
        logger.info("-----使用rest方式调用服务----");
        RespResultVO resultVO = restTemplate.getForObject("http://order-add/orders/getOrder?orderId=" + orderId, RespResultVO.class);
        //RespResultVO resultVO = restTemplate.getForObject("http://order-add-hystrix/orders/getOrder?orderId=" + orderId, RespResultVO.class); //// 测试在服务提供者开启降级服务
        logger.info("-----使用rest方式调用结果:{}----", resultVO);
        return RespResultVO.success(resultVO);
    }

    // 针对 getOrder 方法调用服务失败的降级服务
    public RespResultVO getOrderFallBack(String orderId) {

        logger.info("-----调用order-add服务超时，进行服务降级------");
        //logger.info("-----调用order-add-hystrix服务超时，进行服务降级------");
        logger.info("-----getOrder降级----");
        return RespResultVO.failed("网络异常，查询订单失败，请稍后再试");
    }

}
